package com.pai4j.user.service.relation;
import com.pai4j.common.bean.PAIPageResponseBeanUtil;
import com.pai4j.common.enums.AccountRelationTypeEnum;
import com.pai4j.domain.vo.request.CreateGroupRequestVO;
import com.pai4j.domain.vo.response.AccountRelationListVO;
import com.pai4j.domain.vo.response.AccountRelationResponseVO;
import com.pai4j.domain.vo.response.UserBaseResponseInfoVO;
import com.pai4j.domain.vo.response.WaitConfirmUserResponseVO;
import com.pai4j.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class AccountRelationService {

    @Autowired
    private UserService userService;

    @Autowired
    private User2UserAccountRelationService user2UserAccountRelationService;
    @Autowired
    private User2GroupAccountRelationService user2GroupAccountRelationService;
    @Autowired
    private FriendFollowService friendFollowService;

    /**
     * 订阅/关注
     *
     * @param sourceAccount
     * @param targetAccount
     * @return
     */
    public Boolean subscribe(String sourceAccount, String targetAccount) {
        return this.subscribe(sourceAccount, targetAccount, false);
    }

    /**
     * 订阅/关注（支持是否需要确认参数）
     *
     * @param sourceAccount 源账号
     * @param targetAccount 目标账号
     * @param needConfirmed 是否需要确认，false=普通关注（直接生效），true=好友申请（需要确认）
     * @return
     */
    public Boolean subscribe(String sourceAccount, String targetAccount, boolean needConfirmed) {
        return subscribe(sourceAccount, targetAccount, needConfirmed, null);
    }

    /**
     * 订阅/关注（支持推荐人参数）
     *
     * @param sourceAccount 源账号
     * @param targetAccount 目标账号
     * @param needConfirmed 是否需要确认，false=普通关注（直接生效），true=好友申请（需要确认）
     * @param recommenderAccount 推荐人账号（可选，用于推荐卡片场景）
     * @return
     */
    public Boolean subscribe(String sourceAccount, String targetAccount, boolean needConfirmed, String recommenderAccount) {
        UserBaseResponseInfoVO targetAccountInfo = userService.getUserBaseInfoByUserId(targetAccount);
        Integer roleCode = targetAccountInfo.getRoleCode();
        AbstractAccountRelationService relationService = AccountRelationFactory.getServiceByCode(roleCode);
        return relationService.subscribe(sourceAccount, targetAccount, needConfirmed, recommenderAccount);
    }

    /**
     * 取消订阅/关注
     *
     * @param sourceAccount
     * @param targetAccount
     * @return
     */
    public Boolean unsubscribe(String sourceAccount, String targetAccount) {
        UserBaseResponseInfoVO targetAccountInfo = userService.getUserBaseInfoByUserId(targetAccount);
        Integer roleCode = targetAccountInfo.getRoleCode();
        return AccountRelationFactory.getServiceByCode(roleCode).unsubscribe(sourceAccount, targetAccount);
    }

    /**
     * 确认订阅/关注（通过好友申请）
     * 备注为可选参数，如果提供备注则发送互动消息通知申请人
     *
     * @param confirmAccount 确认账号
     * @param relationId 关系ID
     * @param remark 通过备注（可选）
     * @return
     */
    public Boolean confirmSubscribe(String confirmAccount, Long relationId, String remark) {

        return user2UserAccountRelationService.confirmSubscribe(confirmAccount, relationId, remark);
    }
    
    /**
     * 确认订阅/关注（无备注，向后兼容）
     *
     * @param confirmAccount
     * @param relationId
     * @return
     */
    public Boolean confirmSubscribe(String confirmAccount, Long relationId) {

        return user2UserAccountRelationService.confirmSubscribe(confirmAccount, relationId);
    }

    /**
     * 拒绝订阅/关注（拒绝好友申请）
     * 拒绝理由为可选参数，如果提供理由则发送互动消息通知申请人
     *
     * @param rejectAccount 拒绝账号
     * @param relationId 关系ID
     * @param remark 拒绝理由（可选）
     * @return
     */
    public Boolean rejectSubscribe(String rejectAccount, Long relationId, String remark) {

        return user2UserAccountRelationService.rejectSubscribe(rejectAccount, relationId, remark);
    }
    
    /**
     * 拒绝订阅/关注（无理由，向后兼容）
     *
     * @param rejectAccount
     * @param relationId
     * @return
     */
    public Boolean rejectSubscribe(String rejectAccount, Long relationId) {

        return user2UserAccountRelationService.rejectSubscribe(rejectAccount, relationId);
    }

    public PAIPageResponseBeanUtil<UserBaseResponseInfoVO> pageRelations(String account, Integer type,
                                                                         Integer pageNo, Integer pageSize) {

        return AccountRelationFactory.getServiceByType(type).listRelations(account, pageNo, pageSize);
    }


    /**
     * 查询账号好友列表
     *
     * @param account
     * @return
     */
    public AccountRelationResponseVO listRelations(String account) {
        int pageNo = 1;
        int pageSize = Integer.MAX_VALUE;
        return AccountRelationResponseVO.builder()
                .users(this.getAccountRelationVO(AccountRelationTypeEnum.USER_USER.getType(), account, pageNo, pageSize))
                .groups(this.getAccountRelationVO(AccountRelationTypeEnum.USER_GROUP.getType(), account, pageNo, pageSize))
                .officials(this.getAccountRelationVO(AccountRelationTypeEnum.USER_SUBJECT.getType(), account, pageNo, pageSize))
                .robots(this.getAccountRelationVO(AccountRelationTypeEnum.USER_ROBOT.getType(), account, pageNo, pageSize))
                .build();
    }

    /**
     * 查询账号的好友关系
     *
     * @param account
     * @return
     */
    public List<WaitConfirmUserResponseVO> listWaitConformUsers(String account) {
        /**
         * 因为好友关系审核只存在与 user -> user 关系中，这里我们直接调用具体实现类获取数据即可
         */
        return user2UserAccountRelationService.listWaitConformUsers(account);
    }

    /**
     * 基于工厂模式，获取对应关系实现类，完成好友关系列表查询
     * 走redis，性能完全ok
     *
     * @param relationType
     * @param account
     * @param pageNo
     * @param pageSize
     * @return
     */
    private AccountRelationListVO getAccountRelationVO(Integer relationType, String account, int pageNo, int pageSize) {
        PAIPageResponseBeanUtil<UserBaseResponseInfoVO> apiPageResponseBean =
                AccountRelationFactory.getServiceByType(relationType).listRelations(account, pageNo, pageSize);
        return AccountRelationListVO.builder()
                .count(apiPageResponseBean.getTotal())
                .accounts(apiPageResponseBean.getData())
                .build();
    }

    /**
     * 创建群聊
     *
     * @param createGroupRequest
     * @return
     */
    public String createChatGroup(CreateGroupRequestVO createGroupRequest) {

        return user2GroupAccountRelationService.createChatGroup(createGroupRequest);
    }

    /**
     * 获取用户的粉丝数量（基于friend表，不再依赖account_relation表）
     *
     * @param account 用户账号
     * @param relationType 关系类型（如果是用户对用户关系，从friend表查询；其他类型从account_relation表查询）
     * @return 粉丝数量
     */
    public Long getFollowersCount(String account, Integer relationType) {
        // 用户对用户关系：直接从friend表查询（带缓存）
        if (AccountRelationTypeEnum.USER_USER.getType().equals(relationType)) {
            return friendFollowService.getFollowersCount(account);
        }
        // 其他关系类型：仍使用原有逻辑（从account_relation表查询）
        return AccountRelationFactory.getServiceByType(relationType).getFollowersCount(account);
    }

    /**
     * 获取用户的关注数量（基于friend表，不再依赖account_relation表）
     *
     * @param account 用户账号
     * @param relationType 关系类型（如果是用户对用户关系，从friend表查询；其他类型从account_relation表查询）
     * @return 关注数量
     */
    public Long getFollowingCount(String account, Integer relationType) {
        // 用户对用户关系：直接从friend表查询（带缓存）
        if (AccountRelationTypeEnum.USER_USER.getType().equals(relationType)) {
            return friendFollowService.getFollowingCount(account);
        }
        // 其他关系类型：仍使用原有逻辑（从account_relation表查询）
        return AccountRelationFactory.getServiceByType(relationType).getFollowingCount(account);
    }

    /**
     * 获取用户的粉丝数量（默认用户对用户关系，基于friend表）
     *
     * @param account 用户账号
     * @return 粉丝数量
     */
    public Long getUserFollowersCount(String account) {
        // 直接调用FriendFollowService，完全基于friend表
        return friendFollowService.getFollowersCount(account);
    }

    /**
     * 获取用户的关注数量（默认用户对用户关系，基于friend表）
     *
     * @param account 用户账号
     * @return 关注数量
     */
    public Long getUserFollowingCount(String account) {
        // 直接调用FriendFollowService，完全基于friend表
        return friendFollowService.getFollowingCount(account);
    }

    /**
     * 普通关注（直接生效，无需确认）
     *
     * @param sourceAccount 关注者账号
     * @param targetAccount 被关注者账号
     * @return
     */
    public Boolean follow(String sourceAccount, String targetAccount) {
        return this.subscribe(sourceAccount, targetAccount, false);
    }

    /**
     * 添加好友申请（需要对方确认）
     *
     * @param sourceAccount 申请者账号
     * @param targetAccount 被申请者账号
     * @return
     */
    public Boolean addFriend(String sourceAccount, String targetAccount) {
        return this.subscribe(sourceAccount, targetAccount, true);
    }

    /**
     * 添加好友申请（支持推荐人信息，用于推荐卡片场景）
     *
     * @param sourceAccount 申请者账号
     * @param targetAccount 被申请者账号
     * @param recommenderAccount 推荐人账号（可选）
     * @return
     */
    public Boolean addFriendWithRecommender(String sourceAccount, String targetAccount, String recommenderAccount) {
        return this.subscribe(sourceAccount, targetAccount, true, recommenderAccount);
    }

    /**
     * 语义化：加入群聊（等价于对群账号的普通关注）
     *
     * @param userAccount 用户账号
     * @param groupId 群账号
     * @return 是否成功
     */
    public Boolean joinGroup(String userAccount, String groupId) {
        return this.subscribe(userAccount, groupId, false);
    }

    /**
     * 语义化：退出群聊（等价于取消对群账号的关注）
     *
     * @param userAccount 用户账号
     * @param groupId 群账号
     * @return 是否成功
     */
    public Boolean leaveGroup(String userAccount, String groupId) {
        return this.unsubscribe(userAccount, groupId);
    }

}
